﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Soul.Expressions
{
    public class LambdaContext
    {
        public LambdaOptions Options { get; }

        public LambdaContext(LambdaOptions options)
        {
            Options = options;
        }

        private Dictionary<string, Expression> _tokens = new Dictionary<string, Expression>();

        public bool TryGet(string token, out Expression expression)
        {
            if (_tokens.ContainsKey(token))
            {
                expression = _tokens[token];
                return true;
            }
            expression = null;
            return false;
        }

        public bool TryGetParameter(string token, out ParameterExpression expression)
        {
            var parameter = Options.Parameters.Where(a => a.Name == token).FirstOrDefault();
            if (parameter != null)
            {
                expression = parameter;
                return true;
            }
            expression = null;
            return false;
        }

        internal string AddToken(Expression expression)
        {
            var key = $"#{_tokens.Count}";
            _tokens.Add(key, expression);
            return key;
        }

        internal string Init(string token)
        {
            var buffer = new StringBuilder(token);
            var stringTokens = LambdaParser.GetStringTokens(token);
            foreach (var item in stringTokens)
            {
                var key = AddToken(Expression.Constant(item.Value));
                buffer.Replace(item.Token, key);
            }
            var charTokens = LambdaParser.GetCharTokens(token);
            foreach (var item in charTokens)
            {
                var key = AddToken(Expression.Constant(item.Value));
                buffer.Replace(item.Token, key);
            }
            return buffer.ToString();
        }
    }
}
